using System;
using System.Collections.Generic;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

namespace ExcelTemplateEngine.OpenXML
{
    /// <summary>
    /// 基于OpenXML的共享字符串表实现
    /// </summary>
    public class OpenXMLSharedStringTable : ISharedStringTable
    {
        private readonly SharedStringTablePart _sharedStringPart;
        private readonly Dictionary<string, int> _stringIndex;
        
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sharedStringPart">共享字符串表部件</param>
        public OpenXMLSharedStringTable(SharedStringTablePart sharedStringPart)
        {
            _sharedStringPart = sharedStringPart ?? throw new ArgumentNullException(nameof(sharedStringPart));
            _stringIndex = new Dictionary<string, int>();
            
            // 构建索引
            BuildIndex();
        }
        
        /// <summary>
        /// 共享字符串数量
        /// </summary>
        public int Count => _sharedStringPart.SharedStringTable.Elements<SharedStringItem>().Count();
        
        /// <summary>
        /// 添加字符串到共享字符串表
        /// </summary>
        /// <param name="text">要添加的字符串</param>
        /// <returns>字符串在表中的索引</returns>
        public int AddString(string text)
        {
            if (text == null)
                text = string.Empty;
                
            // 检查是否已存在
            if (_stringIndex.TryGetValue(text, out int existingIndex))
                return existingIndex;
                
            // 添加新字符串
            var sharedStringItem = new SharedStringItem(new Text(text));
            _sharedStringPart.SharedStringTable.Append(sharedStringItem);
            
            var newIndex = Count - 1;
            _stringIndex[text] = newIndex;
            
            // 更新计数
            _sharedStringPart.SharedStringTable.Count = (uint)Count;
            _sharedStringPart.SharedStringTable.UniqueCount = (uint)Count;
            
            return newIndex;
        }
        
        /// <summary>
        /// 根据索引获取字符串
        /// </summary>
        /// <param name="index">字符串索引</param>
        /// <returns>字符串内容</returns>
        public string GetString(int index)
        {
            var items = _sharedStringPart.SharedStringTable.Elements<SharedStringItem>().ToList();
            
            if (index < 0 || index >= items.Count)
                throw new ArgumentOutOfRangeException(nameof(index), $"索引 {index} 超出范围 [0, {items.Count - 1}]");
                
            var item = items[index];
            return item.Text?.Text ?? string.Empty;
        }
        
        /// <summary>
        /// 检查是否包含指定字符串
        /// </summary>
        /// <param name="text">要检查的字符串</param>
        /// <returns>是否包含</returns>
        public bool ContainsString(string text)
        {
            return _stringIndex.ContainsKey(text ?? string.Empty);
        }
        
        /// <summary>
        /// 构建字符串索引
        /// </summary>
        private void BuildIndex()
        {
            _stringIndex.Clear();
            
            var items = _sharedStringPart.SharedStringTable.Elements<SharedStringItem>().ToList();
            for (int i = 0; i < items.Count; i++)
            {
                var text = items[i].Text?.Text ?? string.Empty;
                if (!_stringIndex.ContainsKey(text))
                {
                    _stringIndex[text] = i;
                }
            }
        }
    }
}